HVM: First attempt at domain-resume on save-failure.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 12 Apr 2007 13:13:04 +0000 (14:13 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 12 Apr 2007 13:13:04 +0000 (14:13 +0100)
Not working yet as we are a bit too keen to kill the qemu-dm process,
before we know that the save has been successful.

Signed-off-by: Keir Fraser <keir@xensource.com>
tools/libxc/xc_domain.c
tools/libxc/xc_hvm_build.c
tools/libxc/xc_resume.c
tools/libxc/xenctrl.h
tools/libxc/xenguest.h
tools/python/xen/xend/image.py

index 1b6962d54dea5d2408bdaaf5c08785752985a0cb..948aa3408847523a8b3a4c96d8569efd53607574 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "xc_private.h"
 #include <xen/memory.h>
+#include <xen/hvm/hvm_op.h>
 
 int xc_domain_create(int xc_handle,
                      uint32_t ssidref,
@@ -657,6 +658,44 @@ int xc_domain_send_trigger(int xc_handle,
     return do_domctl(xc_handle, &domctl);
 }
 
+int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
+{
+    DECLARE_HYPERCALL;
+    xen_hvm_param_t arg;
+    int rc;
+
+    hypercall.op     = __HYPERVISOR_hvm_op;
+    hypercall.arg[0] = HVMOP_set_param;
+    hypercall.arg[1] = (unsigned long)&arg;
+    arg.domid = dom;
+    arg.index = param;
+    arg.value = value;
+    if ( lock_pages(&arg, sizeof(arg)) != 0 )
+        return -1;
+    rc = do_xen_hypercall(handle, &hypercall);
+    unlock_pages(&arg, sizeof(arg));
+    return rc;
+}
+
+int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value)
+{
+    DECLARE_HYPERCALL;
+    xen_hvm_param_t arg;
+    int rc;
+
+    hypercall.op     = __HYPERVISOR_hvm_op;
+    hypercall.arg[0] = HVMOP_get_param;
+    hypercall.arg[1] = (unsigned long)&arg;
+    arg.domid = dom;
+    arg.index = param;
+    if ( lock_pages(&arg, sizeof(arg)) != 0 )
+        return -1;
+    rc = do_xen_hypercall(handle, &hypercall);
+    unlock_pages(&arg, sizeof(arg));
+    *value = arg.value;
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
index 751aa9cf7a860db918c357327675f1aef98e6d48..f9e37cb54bf08967f6dfb5018e09c6ce170e3311 100644 (file)
@@ -29,47 +29,6 @@ typedef union
     vcpu_guest_context_t c;
 } vcpu_guest_context_either_t;
 
-
-int xc_set_hvm_param(
-    int handle, domid_t dom, int param, unsigned long value)
-{
-    DECLARE_HYPERCALL;
-    xen_hvm_param_t arg;
-    int rc;
-
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_param;
-    hypercall.arg[1] = (unsigned long)&arg;
-    arg.domid = dom;
-    arg.index = param;
-    arg.value = value;
-    if ( lock_pages(&arg, sizeof(arg)) != 0 )
-        return -1;
-    rc = do_xen_hypercall(handle, &hypercall);
-    unlock_pages(&arg, sizeof(arg));
-    return rc;
-}
-
-int xc_get_hvm_param(
-    int handle, domid_t dom, int param, unsigned long *value)
-{
-    DECLARE_HYPERCALL;
-    xen_hvm_param_t arg;
-    int rc;
-
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_get_param;
-    hypercall.arg[1] = (unsigned long)&arg;
-    arg.domid = dom;
-    arg.index = param;
-    if ( lock_pages(&arg, sizeof(arg)) != 0 )
-        return -1;
-    rc = do_xen_hypercall(handle, &hypercall);
-    unlock_pages(&arg, sizeof(arg));
-    *value = arg.value;
-    return rc;
-}
-
 static void build_e820map(void *e820_page, unsigned long long mem_size)
 {
     struct e820entry *e820entry =
index 3fb6d13adc0022907a25a5a4a4f254ed5a372884..df48fa3dffa0b981dc0eade415317e41827a6ac2 100644 (file)
@@ -3,24 +3,71 @@
 #include "xg_save_restore.h"
 
 #if defined(__i386__) || defined(__x86_64__)
+
+#include <xen/foreign/x86_32.h>
+#include <xen/foreign/x86_64.h>
+#include <xen/hvm/params.h>
+
+/* Need to provide the right flavour of vcpu context for Xen */
+typedef union
+{
+    vcpu_guest_context_x86_64_t c64;
+    vcpu_guest_context_x86_32_t c32;   
+    vcpu_guest_context_t c;
+} vcpu_guest_context_either_t;
+
 static int modify_returncode(int xc_handle, uint32_t domid)
 {
-    vcpu_guest_context_t ctxt;
+    vcpu_guest_context_either_t ctxt;
+    xc_dominfo_t info;
+    xen_capabilities_info_t caps;
     int rc;
 
-    if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
+    {
+        PERROR("Could not get domain info");
+        return -1;
+    }
+
+    /* HVM guests without PV drivers do not have a return code to modify. */
+    if ( info.hvm )
+    {
+        unsigned long irq = 0;
+        xc_get_hvm_param(xc_handle, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
+        if ( !irq )
+            return 0;
+    }
+
+    if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
+    {
+        PERROR("Could not get Xen capabilities\n");
+        return -1;
+    }
+
+    if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt.c)) != 0 )
         return rc;
-    ctxt.user_regs.eax = 1;
-    if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+
+    if ( !info.hvm )
+        ctxt.c.user_regs.eax = 1;
+    else if ( strstr(caps, "x86_64") )
+        ctxt.c64.user_regs.eax = 1;
+    else
+        ctxt.c32.user_regs.eax = 1;
+
+    if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt.c)) != 0 )
         return rc;
 
     return 0;
 }
+
 #else
+
 static int modify_returncode(int xc_handle, uint32_t domid)
 {
     return 0;
+
 }
+
 #endif
 
 static int xc_domain_resume_cooperative(int xc_handle, uint32_t domid)
@@ -65,6 +112,12 @@ static int xc_domain_resume_any(int xc_handle, uint32_t domid)
      * (x86 only) Rewrite store_mfn and console_mfn back to MFN (from PFN).
      */
 #if defined(__i386__) || defined(__x86_64__)
+    if ( info.hvm )
+    {
+        ERROR("Cannot resume uncooperative HVM guests");
+        return rc;
+    }
+
     /* Map the shared info frame */
     shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
                                   PROT_READ, info.shared_info_frame);
index 1073b8bcb5de6596387ec0fd891bfac71575a159..f91dedbc4e53cae2883bcd18802f145f85c5fbd5 100644 (file)
@@ -840,6 +840,9 @@ const char *xc_error_code_to_desc(int code);
  */
 xc_error_handler xc_set_error_handler(xc_error_handler handler);
 
+int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value);
+int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value);
+
 /* PowerPC specific. */
 int xc_alloc_real_mode_area(int xc_handle,
                             uint32_t domid,
index 189d48ed1f86741b8a7dd0de8a18b3146197e187..be30cfe299090e8bf210e46e6ec232874999483c 100644 (file)
@@ -136,11 +136,6 @@ int xc_hvm_build_mem(int xc_handle,
                      const char *image_buffer,
                      unsigned long image_size);
 
-int xc_set_hvm_param(
-    int handle, domid_t dom, int param, unsigned long value);
-int xc_get_hvm_param(
-    int handle, domid_t dom, int param, unsigned long *value);
-
 /* PowerPC specific. */
 int xc_prose_build(int xc_handle,
                    uint32_t domid,
index a4e785d96a63a3282bded27ed5f271268437bf98..d1ea10fe0c66394a633bdd3245bbc2cfd7a544f3 100644 (file)
@@ -284,14 +284,16 @@ class HVMImageHandler(ImageHandler):
         log.debug("acpi           = %d", self.acpi)
         log.debug("apic           = %d", self.apic)
 
-        return xc.hvm_build(domid          = self.vm.getDomid(),
-                            image          = self.kernel,
-                            store_evtchn   = store_evtchn,
-                            memsize        = mem_mb,
-                            vcpus          = self.vm.getVCpuCount(),
-                            pae            = self.pae,
-                            acpi           = self.acpi,
-                            apic           = self.apic)
+        rc = xc.hvm_build(domid          = self.vm.getDomid(),
+                          image          = self.kernel,
+                          store_evtchn   = store_evtchn,
+                          memsize        = mem_mb,
+                          vcpus          = self.vm.getVCpuCount(),
+                          pae            = self.pae,
+                          acpi           = self.acpi,
+                          apic           = self.apic)
+        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
+        return rc
 
     # Return a list of cmd line args to the device models based on the
     # xm config file